package distriKub;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class ChatListener extends Thread {
	
	boolean listening = true;
	
	private int chatPort = ComRules.chatPort;
	
	// Start of making ComListener an event generator
	private List<MessageListener> _listeners = new ArrayList<MessageListener>();

	public synchronized void addMessageListener(MessageListener l) {
		_listeners.add(l);
	} // End of addMessageListener

	public synchronized void removeMessageListener(MessageListener l) {
		_listeners.remove(l);
	} // End of removeMessageListener

	private synchronized void _fireComEvent(String message) {
		ComEvent messageEvent = new ComEvent(this, message);
		Iterator<MessageListener> listeners = _listeners.iterator();
		while (listeners.hasNext()) {
			((MessageListener) listeners.next()).messageReceived(messageEvent);
		} // End of while block
	} // End of _fireComEvent

	// End of making ComListener an event generator
	
	public void closeChatListener(){
		listening = false;
	}
	
	DatagramSocket serverSocket;
	public void run() {
		
		try {
			serverSocket = new DatagramSocket(chatPort);
			
			while (listening){
				
				byte[] receiveData = new byte[1024];
				byte[] sendData = new byte[1024];
				
				DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
				
				// Blocking
				try{serverSocket.receive(receivePacket);} // Could throw an exception if serverSocket was closed from outside the class 
				catch (SocketException SEX){System.out.println("\nNo more listening to UDP ==> ChatListener.java\n"); return;}
				String sentence = new String(receivePacket.getData()).trim();
				
				if (sentence.equals(ComRules.comTerminationString)){ // Listening is being terminated from by the client
					listening = false;
				}
				
				// Debug message
				System.out.println("===> ChatListener.java ===> Got message : " + sentence);
				
				_fireComEvent(sentence); // Distributing the incoming message to all the classed registered to this listener 
	
				// Reading the "return address"
				InetAddress IPAddress = receivePacket.getAddress();
				int port = receivePacket.getPort();
	
				// Preparing a confirmation message and sending it to the source of the incoming message
				String returnValue = "" + sentence.hashCode();
				sendData = returnValue.getBytes();
				DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length, IPAddress, port);
				serverSocket.send(sendPacket);
				
			} // End of while loop
			
			serverSocket.close();

		} catch (Exception e) {
			System.out.println("\n===> ChatListener.java EXCEPTION\n");
			e.printStackTrace();
		}
	}
	
	public DatagramSocket getSocket(){
		return serverSocket;
	}
}